/**
 * 动画工具类
 * 提供常用的动画效果和过渡动画
 */

/**
 * 动画配置接口
 * @typedef {Object} AnimationOptions
 * @property {number} duration
 * @property {string} timingFunction
 * @property {number} delay
 * @property {string} transformOrigin
 */

/**
 * 动画配置接口
 * @typedef {Object} AnimationConfig
 * @property {number} duration
 * @property {string} timingFunction
 * @property {number} delay
 * @property {number|string} iterationCount
 * @property {string} direction
 * @property {string} fillMode
 */

/**
 * 关键帧配置接口
 * @typedef {Object} KeyframeConfig
 */

/**
 * 过渡配置接口
 * @typedef {Object} TransitionConfig
 * @property {string} property
 * @property {number} duration
 * @property {string} timingFunction
 * @property {number} delay
 */

class AnimationUtil {
  /**
   * 创建淡入动画
   */
  static fadeIn(options = {}) {
    const {
      duration = 300,
      timingFunction = 'ease',
      delay = 0
    } = options

    const animation = wx.createAnimation({
      duration,
      timingFunction,
      delay
    })

    animation.opacity(1).step()
    return animation
  }

  /**
   * 创建淡出动画
   */
  static fadeOut(options = {}) {
    const {
      duration = 300,
      timingFunction = 'ease',
      delay = 0
    } = options

    const animation = wx.createAnimation({
      duration,
      timingFunction,
      delay
    })

    animation.opacity(0).step()
    return animation
  }

  /**
   * 创建从下往上滑入动画
   */
  static slideInUp(options = {}) {
    const {
      duration = 400,
      timingFunction = 'ease-out',
      delay = 0
    } = options

    const animation = wx.createAnimation({
      duration,
      timingFunction,
      delay
    })

    animation.translateY(0).opacity(1).step()
    return animation
  }

  /**
   * 创建从上往下滑出动画
   */
  static slideOutDown(options = {}) {
    const {
      duration = 400,
      timingFunction = 'ease-in',
      delay = 0
    } = options

    const animation = wx.createAnimation({
      duration,
      timingFunction,
      delay
    })

    animation.translateY(100).opacity(0).step()
    return animation
  }

  /**
   * 创建从左往右滑入动画
   */
  static slideInLeft(options = {}) {
    const {
      duration = 400,
      timingFunction = 'ease-out',
      delay = 0
    } = options

    const animation = wx.createAnimation({
      duration,
      timingFunction,
      delay
    })

    animation.translateX(0).opacity(1).step()
    return animation
  }

  /**
   * 创建从右往左滑入动画
   */
  static slideInRight(options = {}) {
    const {
      duration = 400,
      timingFunction = 'ease-out',
      delay = 0
    } = options

    const animation = wx.createAnimation({
      duration,
      timingFunction,
      delay
    })

    animation.translateX(0).opacity(1).step()
    return animation
  }

  /**
   * 创建缩放进入动画
   */
  static zoomIn(options = {}) {
    const {
      duration = 300,
      timingFunction = 'ease-out',
      delay = 0,
      transformOrigin = '50% 50%'
    } = options

    const animation = wx.createAnimation({
      duration,
      timingFunction,
      delay,
      transformOrigin
    })

    animation.scale(1).opacity(1).step()
    return animation
  }

  /**
   * 创建缩放退出动画
   */
  static zoomOut(options = {}) {
    const {
      duration = 300,
      timingFunction = 'ease-in',
      delay = 0,
      transformOrigin = '50% 50%'
    } = options

    const animation = wx.createAnimation({
      duration,
      timingFunction,
      delay,
      transformOrigin
    })

    animation.scale(0).opacity(0).step()
    return animation
  }

  /**
   * 创建弹跳动画
   */
  static bounce(options = {}) {
    const {
      duration = 600,
      timingFunction = 'ease',
      delay = 0
    } = options

    const animation = wx.createAnimation({
      duration,
      timingFunction,
      delay
    })

    animation.scale(1.1).step({ duration: duration * 0.3 })
    animation.scale(1).step({ duration: duration * 0.7 })
    return animation
  }

  /**
   * 创建摇摆动画
   */
  static shake(options = {}) {
    const {
      duration = 500,
      timingFunction = 'ease-in-out',
      delay = 0
    } = options

    const animation = wx.createAnimation({
      duration: duration / 5,
      timingFunction,
      delay
    })

    animation.translateX(-10).step()
    animation.translateX(10).step()
    animation.translateX(-10).step()
    animation.translateX(10).step()
    animation.translateX(0).step()
    return animation
  }

  /**
   * 创建旋转动画
   */
  static rotate(options = {}) {
    const {
      duration = 300,
      timingFunction = 'ease',
      delay = 0,
      angle = 360
    } = options

    const animation = wx.createAnimation({
      duration,
      timingFunction,
      delay
    })

    animation.rotate(angle).step()
    return animation
  }

  /**
   * 创建脉冲动画
   */
  static pulse(options = {}) {
    const {
      duration = 1000,
      timingFunction = 'ease-in-out',
      delay = 0
    } = options

    const animation = wx.createAnimation({
      duration: duration / 2,
      timingFunction,
      delay
    })

    animation.scale(1.05).step()
    animation.scale(1).step()
    return animation
  }

  /**
   * 创建翻转动画
   */
  static flip(options = {}) {
    const {
      duration = 600,
      timingFunction = 'ease-in-out',
      delay = 0,
      axis = 'Y'
    } = options

    const animation = wx.createAnimation({
      duration: duration / 2,
      timingFunction,
      delay
    })

    if (axis === 'Y') {
      animation.rotateY(90).step()
      animation.rotateY(0).step()
    } else {
      animation.rotateX(90).step()
      animation.rotateX(0).step()
    }
    
    return animation
  }

  /**
   * 创建组合动画序列
   */
  static sequence(animations) {
    const animation = wx.createAnimation({
      duration: 0,
      timingFunction: 'linear'
    })

    animations.forEach(animationFn => {
      const anim = animationFn()
      // 这里需要根据实际情况调整，因为微信小程序的动画API限制
      animation.step()
    })

    return animation
  }

  /**
   * 页面切换动画 - 从右滑入
   */
  static pageSlideInRight() {
    return this.slideInRight({ duration: 300, timingFunction: 'ease-out' })
  }

  /**
   * 页面切换动画 - 向左滑出
   */
  static pageSlideOutLeft() {
    const animation = wx.createAnimation({
      duration: 300,
      timingFunction: 'ease-in'
    })

    animation.translateX(-100).opacity(0).step()
    return animation
  }

  /**
   * 列表项动画 - 依次显示
   */
  static staggeredFadeIn(index, baseDelay = 100) {
    return this.fadeIn({
      duration: 400,
      delay: index * baseDelay,
      timingFunction: 'ease-out'
    })
  }

  /**
   * 按钮点击反馈动画
   */
  static buttonPress() {
    const animation = wx.createAnimation({
      duration: 150,
      timingFunction: 'ease-out'
    })

    animation.scale(0.95).step({ duration: 75 })
    animation.scale(1).step({ duration: 75 })
    return animation
  }

  /**
   * 加载动画
   */
  static loading() {
    const animation = wx.createAnimation({
      duration: 1000,
      timingFunction: 'linear'
    })

    animation.rotate(360).step()
    return animation
  }

  /**
   * 心跳动画
   */
  static heartbeat() {
    const animation = wx.createAnimation({
      duration: 300,
      timingFunction: 'ease-in-out'
    })

    animation.scale(1.2).step({ duration: 150 })
    animation.scale(1).step({ duration: 150 })
    return animation
  }

  /**
   * 弹性进入动画
   */
  static elasticIn(options = {}) {
    const {
      duration = 800,
      delay = 0
    } = options

    const animation = wx.createAnimation({
      duration,
      timingFunction: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
      delay
    })

    animation.scale(1).opacity(1).step()
    return animation
  }

  /**
   * 磁性吸附效果
   */
  static magneticHover(options = {}) {
    const {
      duration = 200,
      timingFunction = 'ease-out'
    } = options

    const animation = wx.createAnimation({
      duration,
      timingFunction
    })

    animation.scale(1.05).translateY(-2).step()
    return animation
  }

  /**
   * 磁性释放效果
   */
  static magneticRelease(options = {}) {
    const {
      duration = 200,
      timingFunction = 'ease-out'
    } = options

    const animation = wx.createAnimation({
      duration,
      timingFunction
    })

    animation.scale(1).translateY(0).step()
    return animation
  }

  /**
   * 微交互点击效果
   */
  static microInteraction(options = {}) {
    const {
      duration = 150,
      timingFunction = 'ease-out'
    } = options

    const animation = wx.createAnimation({
      duration,
      timingFunction
    })

    animation.scale(0.95).step({ duration: 75 })
    animation.scale(1).step({ duration: 75 })
    return animation
  }

  /**
   * 呼吸灯效果
   */
  static breathe(options = {}) {
    const {
      duration = 2000,
      timingFunction = 'ease-in-out'
    } = options

    const animation = wx.createAnimation({
      duration,
      timingFunction
    })

    animation.opacity(0.3).step({ duration: 1000 })
    animation.opacity(1).step({ duration: 1000 })
    return animation
  }

  /**
   * 浮动效果
   */
  static float(options = {}) {
    const {
      duration = 3000,
      timingFunction = 'ease-in-out'
    } = options

    const animation = wx.createAnimation({
      duration,
      timingFunction
    })

    animation.translateY(-10).step({ duration: 1500 })
    animation.translateY(0).step({ duration: 1500 })
    return animation
  }

  /**
   * 渐变显示动画
   */
  static gradualShow(options = {}) {
    const {
      duration = 600,
      timingFunction = 'cubic-bezier(0.4, 0, 0.2, 1)',
      delay = 0
    } = options

    const animation = wx.createAnimation({
      duration,
      timingFunction,
      delay
    })

    animation.opacity(1).translateY(0).scale(1).step()
    return animation
  }

  /**
   * 卡片翻转效果
   */
  static cardFlip(options = {}) {
    const {
      duration = 600,
      timingFunction = 'ease-in-out'
    } = options

    const animation = wx.createAnimation({
      duration,
      timingFunction
    })

    animation.rotateY(180).step({ duration: 300 })
    animation.rotateY(0).step({ duration: 300 })
    return animation
  }

  /**
   * 涟漪效果
   */
  static ripple(options = {}) {
    const {
      duration = 600,
      timingFunction = 'ease-out'
    } = options

    const animation = wx.createAnimation({
      duration,
      timingFunction
    })

    animation.scale(1.2).opacity(0).step()
    return animation
  }
}

/**
 * 页面过渡动画管理器
 */
class PageTransition {
  static currentAnimation = null

  /**
   * 执行页面进入动画
   */
  static enter(type = 'slideUp') {
    return new Promise((resolve) => {
      let animation

      switch (type) {
        case 'slideUp':
          animation = AnimationUtil.slideInUp({ duration: 400 })
          break
        case 'slideRight':
          animation = AnimationUtil.slideInRight({ duration: 400 })
          break
        case 'fade':
          animation = AnimationUtil.fadeIn({ duration: 400 })
          break
        case 'zoom':
          animation = AnimationUtil.zoomIn({ duration: 400 })
          break
        default:
          animation = AnimationUtil.slideInUp({ duration: 400 })
      }

      this.currentAnimation = animation
      setTimeout(resolve, 400)
    })
  }

  /**
   * 执行页面退出动画
   */
  static exit(type = 'slideDown') {
    return new Promise((resolve) => {
      let animation

      switch (type) {
        case 'slideDown':
          animation = AnimationUtil.slideOutDown({ duration: 300 })
          break
        case 'slideLeft':
          animation = AnimationUtil.pageSlideOutLeft()
          break
        case 'fade':
          animation = AnimationUtil.fadeOut({ duration: 300 })
          break
        case 'zoom':
          animation = AnimationUtil.zoomOut({ duration: 300 })
          break
        default:
          animation = AnimationUtil.slideOutDown({ duration: 300 })
      }

      this.currentAnimation = animation
      setTimeout(resolve, 300)
    })
  }

  /**
   * 获取当前动画
   */
  static getCurrentAnimation() {
    return this.currentAnimation
  }

  /**
   * 清除当前动画
   */
  static clear() {
    this.currentAnimation = null
  }
}

module.exports = AnimationUtil
module.exports.AnimationUtil = AnimationUtil
module.exports.PageTransition = PageTransition